package com.zz.demo.thread;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用生产者和消费者来进行一对一的交替打印
 */
public class producerAndConsumer {
    public static void main(String[] args) {
        MyServer myServer = new MyServer();
        MyConditionSet myConditionSet = new MyConditionSet(myServer);
        MyConditionGet myConditionGet = new MyConditionGet(myServer);
//        myConditionSecond.start();
        myConditionSet.start();
        myConditionGet.start();
    }
//    public static void main(String[] args) {
//        MyServer myServer = new MyServer();
//        MyConditionGet[] myConditionGets = new MyConditionGet[10];
//        MyConditionSet[] myConditionSets = new MyConditionSet[10];
//        for (int i = 0; i < 10; i ++) {
//            myConditionGets[i] = new MyConditionGet(myServer);
//            myConditionSets[i] = new MyConditionSet(myServer);
//            myConditionGets[i].start();
//            myConditionSets[i].start();
//        }
//    }
}

class MyServer {
    private ReentrantLock lock = new ReentrantLock();
    public Condition condition = lock.newCondition();
    public Boolean flag = false;

    public void set() {
        try {
            lock.lock();
            while (flag) {
                System.out.println("可能会有连续的hello进行打印");
                condition.await();
            }
            System.out.println("当前线程名: " + Thread.currentThread().getName() + " hello");
            flag = true;
            condition.signal();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void get() {
        try {
            lock.lock();
            // 如果说标志位不是为false的话，那么本线程就一直在等待状态。
            while (! flag) {
                System.out.println("可能会有连续的lemon进行打印");
                condition.await();
            }
            System.out.println("当前线程名：" + Thread.currentThread().getName() + " lemon");
            flag = false;
            condition.signal();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}

class MyConditionSet extends Thread {
    private MyServer myServer;

    public MyConditionSet(MyServer myServer) {
        super();
        this.myServer = myServer;
    }
    public void run() {
        for (int i = 0; i < 10;i ++) {
            myServer.set();
        }
    }
}
class MyConditionGet extends Thread {
    private MyServer myServer;

    public MyConditionGet(MyServer myServer) {
        super();
        this.myServer = myServer;
    }
    public void run() {
        for (int i = 0; i < 10;i ++) {
            myServer.get();
        }
    }
}
